
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2010, Adam Kubach
//  All rights reserved.
//  BSD License: http://www.opensource.org/licenses/bsd-license.html
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
//  Information for a tile.
//
///////////////////////////////////////////////////////////////////////////////

#include "Minerva/Common/TileKey.h"

using namespace Minerva::Common;


///////////////////////////////////////////////////////////////////////////////
//
//  Constructor.
//
///////////////////////////////////////////////////////////////////////////////

TileKey::TileKey() :
  _row ( 0 ),
  _column ( 0 ),
  _level ( 0 ),
  _extents ( -180.0, -90.0, 180.0, 90.0 ),
  _imageSize ( 256, 256 ),
  _meshSize ( 17, 17 )
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Destructor.
//
///////////////////////////////////////////////////////////////////////////////

TileKey::~TileKey()
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Split into 4 child keys.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::split ( ChildrenKeys& keys ) const
{
  const unsigned int level ( this->level() + 1 );
  const unsigned int row ( this->row() * 2 );
  const unsigned int column ( this->column() * 2 );
  
  // Extents for child tiles.
  Extents ll, lr, ul, ur;
  this->extents().split ( ll, lr, ul, ur );
  
  keys[UPPER_LEFT] = new TileKey;
  keys[UPPER_LEFT]->row ( row );
  keys[UPPER_LEFT]->column ( column );
  keys[UPPER_LEFT]->level ( level );
  keys[UPPER_LEFT]->extents ( ul );
  keys[UPPER_LEFT]->imageSize ( this->imageSize() );
  keys[UPPER_LEFT]->meshSize ( this->meshSize() );

  keys[LOWER_LEFT] = new TileKey;
  keys[LOWER_LEFT]->row ( row + 1 );
  keys[LOWER_LEFT]->column ( column );
  keys[LOWER_LEFT]->level ( level );
  keys[LOWER_LEFT]->extents ( ll );
  keys[LOWER_LEFT]->imageSize ( this->imageSize() );
  keys[LOWER_LEFT]->meshSize ( this->meshSize() );
  
  keys[UPPER_RIGHT] = new TileKey;
  keys[UPPER_RIGHT]->row ( row );
  keys[UPPER_RIGHT]->column ( column + 1 );
  keys[UPPER_RIGHT]->level ( level );
  keys[UPPER_RIGHT]->extents ( ur );
  keys[UPPER_RIGHT]->imageSize ( this->imageSize() );
  keys[UPPER_RIGHT]->meshSize ( this->meshSize() );
  
  keys[LOWER_RIGHT] = new TileKey;
  keys[LOWER_RIGHT]->row ( row + 1 );
  keys[LOWER_RIGHT]->column ( column + 1 );
  keys[LOWER_RIGHT]->level ( level );
  keys[LOWER_RIGHT]->extents ( lr );
  keys[LOWER_RIGHT]->imageSize ( this->imageSize() );
  keys[LOWER_RIGHT]->meshSize ( this->meshSize() );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the row.
//
///////////////////////////////////////////////////////////////////////////////

unsigned int TileKey::row() const
{
  return _row;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the row.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::row ( unsigned int value )
{
  _row = value;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the column.
//
///////////////////////////////////////////////////////////////////////////////

unsigned int TileKey::column() const
{
  return _column;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the column.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::column ( unsigned int value )
{
  _column = value;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the level.
//
///////////////////////////////////////////////////////////////////////////////

unsigned int TileKey::level() const
{
  return _level;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the level.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::level ( unsigned int value )
{
  _level = value;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the extents.
//
///////////////////////////////////////////////////////////////////////////////

const Minerva::Common::Extents& TileKey::extents() const
{
  return _extents;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the extents.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::extents ( const Minerva::Common::Extents& e )
{
  _extents = e;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the mesh size.
//
///////////////////////////////////////////////////////////////////////////////

const Usul::Math::Vec2ui& TileKey::imageSize() const
{
  return _imageSize;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the image size.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::imageSize ( const Usul::Math::Vec2ui& value )
{
  _imageSize = value;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the mesh size.
//
///////////////////////////////////////////////////////////////////////////////

const Usul::Math::Vec2ui& TileKey::meshSize() const
{
  return _meshSize;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the mesh size.
//
///////////////////////////////////////////////////////////////////////////////

void TileKey::meshSize ( const Usul::Math::Vec2ui& size )
{
  _meshSize = size;
}
